package com.zhuiyun.project.api.system.user.service.impl;

import com.zhuiyun.project.api.system.role.entity.SysRole;
import com.zhuiyun.project.api.system.role.mapper.SysRoleMapper;
import com.zhuiyun.project.api.system.user.entity.SysUser;
import com.zhuiyun.project.api.system.user.entity.SysUserRole;
import com.zhuiyun.project.api.system.user.mapper.SysUserMapper;
import com.zhuiyun.project.api.system.user.mapper.SysUserRoleMapper;
import com.zhuiyun.project.api.system.user.model.SysUserModel;
import com.zhuiyun.project.api.system.user.service.SysUserService;
import com.zhuiyun.project.common.constant.UserConstants;
import com.zhuiyun.project.common.errorCode.CommonException;
import com.zhuiyun.project.common.errorCode.EmErrorCode;
import com.zhuiyun.project.common.response.CommonResult;
import com.zhuiyun.project.utils.*;
import com.zhuiyun.project.utils.pageUtil.MybatisPageHelper;
import com.zhuiyun.project.utils.pageUtil.PageRequest;
import com.zhuiyun.project.utils.pageUtil.PageResult;
import com.zhuiyun.project.utils.validator.ValidatorUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName SysUserServiceImpl
 * @Description 用户管理服务类 用于实现用户的增删改查 登录 注销
 * @Author zcy
 * @Date 2023/3/24 16:15
 **/
@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    SysUserRoleMapper sysUserRoleMapper;

    @Resource
    SysRoleMapper sysRoleMapper;


    /**
    * @Author hbx
    * @Description 通过邮箱查询用户
    * @Date 2023/6/22 11:13
    * @param emailAccount
    */
    @Override
    public SysUser getUserByEmailAccount(String emailAccount) {
        // 判断用户登录名是否为空
        if(ObjectUtils.isNotEmpty(emailAccount)){
            // 使用Example表达式查询登录人信息
            Example example = new Example(SysUser.class);
            example.createCriteria().andEqualTo("email",emailAccount);
            return sysUserMapper.selectOneByExample(example);
        }else{
            return null;
        }
    }

    /**
    * @Author hbx
    * @Description 更新登录成功后更新用户信息
    * @Date 2023/6/22 11:14
    * @param sysUser
    */
    @Override
    public void updateUserByLogin(SysUser sysUser) {
        if(ObjectUtils.isNotEmpty(sysUser)&&ObjectUtils.isNotEmpty(sysUser.getId())){
            sysUserMapper.updateByPrimaryKeySelective(sysUser);
        }
    }
    /**
    * @Author hbx
    * @Description 新增用户
    * @Date 2023/6/22 11:14
    * @param sysUser
    */
    @Override
    public int saveUser(SysUser sysUser) throws CommonException {
        // 设置密码
        sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
        int i = sysUserMapper.insert(sysUser);
        return i;
    }

    /**
    * @Author hbx
    * @Description 修改用户信息
    * @Date 2023/6/22 11:15
    * @param sysUserModel
    */
    @Override
    public CommonResult updateUser(SysUserModel sysUserModel) throws CommonException {
        // 验证参数的规范性
        if(ValidatorUtil.ValidationObject(sysUserModel)){
            SysUser sysUser = new SysUser();
            // sysUserModel 对象拷贝成 sysUser
            BeanUtils.copy(sysUserModel, sysUser);
            int i = sysUserMapper.updateByPrimaryKeySelective(sysUser);
            if(i>0){
                return CommonResult.ok(EmErrorCode.UPDATE_OK);
            }else{
                return CommonResult.ok(EmErrorCode.UPDATE_ERROR);
            }
        }else{
            return CommonResult.ok(EmErrorCode.UPDATE_ERROR);
        }
    }

    /**
    * @Author hbx
    * @Description 删除用户
    * @Date 2023/6/22 11:15
    * @param id
    */
    @Override
    public CommonResult delUserById(Integer id) throws CommonException {
        // 判断是否id为空
        if(ObjectUtils.isNotEmpty(id)){
            int i = sysUserMapper.deleteByPrimaryKey(id);
            // 判断是否操作成功
            if(i>0){
                return CommonResult.ok(EmErrorCode.DELETE_OK);
            }else{
                return CommonResult.ok(EmErrorCode.DELETE_ERROR);
            }
        }else{
            throw new CommonException(EmErrorCode.ID_NULL);
        }
    }

    /**
    * @Author hbx
    * @Description 分页查询
    * @Date 2023/6/22 11:15
    * @param sysUserModel
    * @param pageRequest
    */
    @Override
    public CommonResult getUserByPage(SysUserModel sysUserModel, PageRequest pageRequest) {
        // 设置分页
        MybatisPageHelper.startPage(pageRequest);
        Example example = new Example(SysUser.class);
        // 设置模糊查询
        if(ObjectUtils.isNotEmpty(sysUserModel.getUserName())){
            example.createCriteria().andLike("userName","%"+sysUserModel.getUserName()+"%");
        }
        PageResult pageResult = MybatisPageHelper.getPageResult(sysUserMapper.selectByExample(example));
        return CommonResult.ok(pageResult);
    }

    /**
    * @Author hbx
    * @Description 根据手机号查询用户信息
    * @Date 2023/6/22 11:15
    * @param phoneAccount
    */
    @Override
    public SysUser getUserByPhoneAccount(String phoneAccount) {
        // 判断用户登录名是否为空
        if(ObjectUtils.isNotEmpty(phoneAccount)){
            // 使用Example表达式查询登录人信息
            Example example = new Example(SysUser.class);
            example.createCriteria().andEqualTo("phone",phoneAccount);
            return sysUserMapper.selectOneByExample(example);
        }else{
            return null;
        }
    }

    /**
    * @Author hbx
    * @Description 根据条件分页查询已分配用户角色列表
    * @Date 2023/6/22 11:16
    * @param pageRequest
    * @param user
    */
    @Override
    public PageResult selectAllocatedList(PageRequest pageRequest, SysUser user) {
        MybatisPageHelper.startPage(pageRequest);
        List<SysUser> sysUsers = sysUserMapper.selectAllocatedList(user);
        PageResult pageResult = MybatisPageHelper.getPageResult(sysUsers);
        return pageResult;
    }

    /*
    * @Author hbx
    * @Description 查询未分配用户角色列表
    * @Date 2023/6/22 11:16
    * @param pageRequest
    * @param user
    */
    @Override
    public PageResult selectUnallocatedList(PageRequest pageRequest, SysUser user) {
        MybatisPageHelper.startPage(pageRequest);
        List<SysUser> sysUsers = sysUserMapper.selectUnallocatedList(user);;
        PageResult pageResult = MybatisPageHelper.getPageResult(sysUsers);
        return pageResult;
    }


    /**
    * @Author hbx
    * @Description 根据条件分页查询用户列表
    * @Date 2023/6/22 11:16
    * @param pageRequest
    * @param user
    */
    @Override
    public PageResult selectUserList(PageRequest pageRequest, SysUser user) {
        MybatisPageHelper.startPage(pageRequest);
        List<SysUser> sysUserList = sysUserMapper.selectUserList(user);
        PageResult pageResult = MybatisPageHelper.getPageResult(sysUserList);
        return pageResult;
    }

    /**
    * @Author hbx
    * @Description 校验用户名称是否唯一
    * @Date 2023/6/21 15:31
    * @param user
    */
    @Override
    public boolean checkLoginNameUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
        SysUser info = sysUserMapper.checkLoginNameUnique(user.getLoginName());
        if (StringUtils.isNotNull(info) && info.getId().longValue() != userId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
    * @Author hbx
    * @Description 校验手机号码是否唯一
    * @Date 2023/6/21 15:35
    * @param user
    */
    @Override
    public boolean checkPhoneUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
        SysUser info = sysUserMapper.checkPhoneUnique(user.getPhone());
        if (StringUtils.isNotNull(info) && info.getId().longValue() != userId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
    * @Author hbx
    * @Description 校验email是否唯一
    * @Date 2023/6/21 15:39
    * @param user
    */
    @Override
    public boolean checkEmailUnique(SysUser user) {
        Long userId = StringUtils.isNull(user.getId()) ? -1L : user.getId();
        SysUser info = sysUserMapper.checkEmailUnique(user.getEmail());
        if (StringUtils.isNotNull(info) && info.getId().longValue() != userId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
    * @Author hbx
    * @Description 新增用户信息
    * @Date 2023/6/22 11:16
    * @param user
    */
    @Override
    public int insertUser(SysUser user) {
        // 新增用户信息
        int rows = sysUserMapper.insertUser(user);
        // 新增用户与角色管理
        insertUserRole(user);
        return rows;
    }

    /**
    * @Author hbx
    * @Description 校验用户是否有数据权限
    * @Date 2023/6/22 11:17
    * @param id
    */
    @Override
    public void checkUserDataScope(Integer id)
    {
        if (!SysUser.isAdmin(SecurityUtils.getUserId()))
        {
            SysUser user = new SysUser();
            user.setId(id);
            PageRequest pageResult = new PageRequest();
            PageResult users = this.selectUserList(pageResult,user);
            if (StringUtils.isEmpty((CharSequence) users))
            {
                throw new ServiceException("没有权限访问用户数据！");
            }
        }
    }

    /**
    * @Author hbx
    * @Description 通过用户ID查询用户
    * @Date 2023/6/22 11:17
    * @param id
    */
    @Override
    public SysUser selectUserById(Integer id) {
        return sysUserMapper.selectUserById(id);
    }

    /*
    * @Author hbx
    * @Description 校验用户是否允许操作
    * @Date 2023/6/22 11:17
    * @param user
    */
    @Override
    public void checkUserAllowed(SysUser user) {
        if (StringUtils.isNotNull(user.getId()) && user.isAdmin())
        {
            throw new ServiceException("不允许操作超级管理员用户");
        }
    }

    /**
    * @Author hbx
    * @Description 修改用户信息
    * @Date 2023/6/22 11:17
    * @param user
    */
    @Override
    public int updateUsers(SysUser user) {
        Integer userId = user.getId();
        // 删除用户与角色关联
        sysUserRoleMapper.deleteUserRoleByUserId(userId);
        // 新增用户与角色管理
        insertUserRole(user);
        return sysUserMapper.updateUser(user);
    }


    /**
    * @Author hbx
    * @Description 通过用户ID删除用户
    * @Date 2023/6/22 11:17
    * @param userId
    */
    @Override
    @Transactional
    public int deleteUserById(Integer userId)
    {
        // 删除用户与角色关联
        sysUserRoleMapper.deleteUserRoleByUserId(userId);
        return sysUserMapper.deleteUserById(userId);
    }

    /**
    * @Author hbx
    * @Description 批量删除用户信息
    * @Date 2023/6/22 11:17
    * @param userIds
    */
    @Override
    @Transactional
    public CommonResult deleteUserByIds(Integer[] userIds) {
        for (Integer id : userIds) {
            checkUserAllowed(new SysUser(id));
            checkUserDataScope(id);
        }
        // 删除用户与角色关联
        sysUserRoleMapper.deleteUserRole(userIds);
        int i = sysUserMapper.deleteUserByIds(userIds);
        if (i > 0) {
            return CommonResult.ok(EmErrorCode.DELETE_OK);
        } else {
            return CommonResult.error(EmErrorCode.DELETE_ERROR);
        }
    }

    /**
    * @Author hbx
    * @Description 修改用户状态
    * @Date 2023/6/22 11:18
    * @param user
    */
    @Override
    public int updateUserStatus(SysUser user) {
        return sysUserMapper.updateUser(user);
    }

    /**
    * @Author hbx
    * @Description 根据用户名查询用户信息
    * @Date 2023/6/27 14:24
    * @param loginName
    */
    @Override
    public SysUser getUserByLoginName(String loginName) {
        SysUser list  = sysUserMapper.getUserByLoginName(loginName);
        return list;
    }


    /**
    * @Author hbx
    * @Description 新增用户角色信息
    * @Date 2023/6/22 11:18
    * @param user
    */
    private void insertUserRole(SysUser user) {
        this.insertUserRole(user.getId(), user.getRoleIds());
    }

    /**
    * @Author hbx
    * @Description 新增用户角色信息
    * @Date 2023/6/22 11:18
    * @param userId
    * @param roleIds
    */
    public void insertUserRole(Integer userId, Long[] roleIds)
    {
        if (StringUtils.isNotEmpty(roleIds))
        {
            // 新增用户与角色管理
            List<SysUserRole> list = new ArrayList<SysUserRole>(roleIds.length);
            for (Long roleId : roleIds)
            {
                SysUserRole ur = new SysUserRole();
                ur.setUserId(Long.valueOf(userId));
                ur.setRoleId(roleId);
                list.add(ur);
            }
            sysUserRoleMapper.batchUserRole(list);
        }
    }

    /**
     * 查询用户所属角色组
     *
     * @param loginName 登录用户名
     * @return 结果
     */
    @Override
    public String selectUserRoleGroup(String loginName)
    {
        List<SysRole> list = sysRoleMapper.selectRolesByLoginName(loginName);
        if (CollectionUtils.isEmpty(list))
        {
            return StringUtils.EMPTY;
        }
        return list.stream().map(SysRole::getRoleName).collect(Collectors.joining(","));
    }

    @Override
    public int resetUserPwd(Integer id, String encryptPassword) {
        return sysUserMapper.resetUserPwd(id, encryptPassword);
    }

    /**
    * @Description 修改个人基本信息
    * @Author lzy
    * @Date 2023/8/2 14:29
    * @Return int
    * @param sysUser
    */
    @Override
    public int updateProfile(SysUser sysUser) {
        int i = sysUserMapper.updateUser(sysUser);
        return i;
    }

    /**
    * @Description 修改用户头像id
    * @Author lzy
    * @Date 2023/8/4 16:20
    * @Return int
    * @param avatarId
    */
    @Override
    public int updateAvatarId(String avatarId, Integer userId) {
        int i = sysUserMapper.updateAvatarId(avatarId, userId);
        return i;
    }

}
